Lietuvių

Išmokite mastelio keitimui pritaikytus GraphQL schemos projektavimo modelius, skirtus tvirtoms ir lengvai prižiūrimoms API kurti, pritaikytoms įvairiai pasaulinei auditorijai. Įvaldykite schemų sujungimą, federaciją ir modularizaciją.

GraphQL schemos projektavimas: mastelio keitimui pritaikyti modeliai globalioms API

GraphQL tapo galinga alternatyva tradicinėms REST API, suteikdama klientams lankstumo prašyti būtent tų duomenų, kurių jiems reikia. Tačiau, kai jūsų GraphQL API tampa sudėtingesnė ir platesnės apimties – ypač aptarnaujant globalią auditoriją su įvairiais duomenų poreikiais – kruopštus schemos projektavimas tampa gyvybiškai svarbus norint užtikrinti palaikomumą, mastelio keitimą ir našumą. Šiame straipsnyje nagrinėjami keli mastelio keitimui pritaikyti GraphQL schemos projektavimo modeliai, kurie padės jums sukurti tvirtas API, galinčias atlaikyti globalios programos reikalavimus.

Mąstelio keitimui pritaikyto schemos projektavimo svarba

Gerai suprojektuota GraphQL schema yra sėkmingos API pagrindas. Ji nustato, kaip klientai gali sąveikauti su jūsų duomenimis ir paslaugomis. Prastas schemos projektavimas gali sukelti daugybę problemų, įskaitant:

Globalioms programoms šios problemos sustiprėja. Skirtingi regionai gali turėti skirtingus duomenų reikalavimus, reguliavimo apribojimus ir našumo lūkesčius. Mąstelio keitimui pritaikytas schemos projektavimas leidžia efektyviai spręsti šiuos iššūkius.

Pagrindiniai mąstelio keitimui pritaikyto schemos projektavimo principai

Prieš gilinantis į konkrečius modelius, apibrėžkime kelis pagrindinius principus, kuriais turėtumėte vadovautis projektuodami schemą:

Mąstelio keitimui pritaikyti schemos projektavimo modeliai

Štai keli mąstelio keitimui pritaikyti schemos projektavimo modeliai, kuriuos galite naudoti kurdami tvirtas GraphQL API:

1. Schemų sujungimas (Schema Stitching)

Schemų sujungimas leidžia sujungti kelias GraphQL API į vieną, unifikuotą schemą. Tai ypač naudinga, kai skirtingos komandos ar paslaugos yra atsakingos už skirtingas jūsų duomenų dalis. Tai tarsi turėti kelias mini-API ir sujungti jas per „švyturio“ (gateway) API.

Kaip tai veikia:

  1. Kiekviena komanda ar paslauga pateikia savo GraphQL API su savo schema.
  2. Centrinė švyturio paslauga naudoja schemų sujungimo įrankius (pvz., Apollo Federation ar GraphQL Mesh), kad sujungtų šias schemas į vieną, unifikuotą schemą.
  3. Klientai sąveikauja su švyturio paslauga, kuri nukreipia užklausas į atitinkamas pagrindines API.

Pavyzdys:

Įsivaizduokite e. prekybos platformą su atskiromis API produktams, vartotojams ir užsakymams. Kiekviena API turi savo schemą:

  
    # Produktų API
    type Product {
      id: ID!
      name: String!
      price: Float!
    }

    type Query {
      product(id: ID!): Product
    }

    # Vartotojų API
    type User {
      id: ID!
      name: String!
      email: String!
    }

    type Query {
      user(id: ID!): User
    }

    # Užsakymų API
    type Order {
      id: ID!
      userId: ID!
      productId: ID!
      quantity: Int!
    }

    type Query {
      order(id: ID!): Order
    }
  

Švyturio paslauga gali sujungti šias schemas, kad sukurtų unifikuotą schemą:

  
    type Product {
      id: ID!
      name: String!
      price: Float!
    }

    type User {
      id: ID!
      name: String!
      email: String!
    }

    type Order {
      id: ID!
      user: User! @relation(field: "userId")
      product: Product! @relation(field: "productId")
      quantity: Int!
    }

    type Query {
      product(id: ID!): Product
      user(id: ID!): User
      order(id: ID!): Order
    }
  

Atkreipkite dėmesį, kaip Order tipas dabar apima nuorodas į User ir Product, nors šie tipai yra apibrėžti atskirose API. Tai pasiekiama naudojant schemų sujungimo direktyvas (kaip @relation šiame pavyzdyje).

Privalumai:

Svarstytini aspektai:

2. Schemų federacija (Schema Federation)

Schemų federacija yra schemų sujungimo evoliucija, skirta spręsti kai kuriuos jos apribojimus. Ji suteikia labiau deklaratyvų ir standartizuotą požiūrį į GraphQL schemų komponavimą.

Kaip tai veikia:

  1. Kiekviena paslauga pateikia GraphQL API ir anotuoją savo schemą federacijos direktyvomis (pvz., @key, @extends, @external).
  2. Centrinė švyturio paslauga (naudojant Apollo Federation) naudoja šias direktyvas, kad sukurtų supergrafą – visos federacinės schemos reprezentaciją.
  3. Švyturio paslauga naudoja supergrafą, kad nukreiptų užklausas į atitinkamas pagrindines paslaugas ir išspręstų priklausomybes.

Pavyzdys:

Naudojant tą patį e. prekybos pavyzdį, federacinės schemos galėtų atrodyti taip:

  
    # Produktų API
    type Product @key(fields: "id") {
      id: ID!
      name: String!
      price: Float!
    }

    type Query {
      product(id: ID!): Product
    }

    # Vartotojų API
    type User @key(fields: "id") {
      id: ID!
      name: String!
      email: String!
    }

    type Query {
      user(id: ID!): User
    }

    # Užsakymų API
    type Order {
      id: ID!
      userId: ID!
      productId: ID!
      quantity: Int!
      user: User! @requires(fields: "userId")
      product: Product! @requires(fields: "productId")
    }

    extend type Query {
      order(id: ID!): Order
    }
  

Atkreipkite dėmesį į federacijos direktyvų naudojimą:

Privalumai:

Svarstytini aspektai:

3. Modulinis schemos projektavimas

Modulinis schemos projektavimas apima didelės, monolitinės schemos suskaidymą į mažesnius, lengviau valdomus modulius. Tai palengvina atskirų API dalių supratimą, keitimą ir pakartotinį naudojimą, net ir nesinaudojant federacinėmis schemomis.

Kaip tai veikia:

  1. Nustatykite logines ribas savo schemoje (pvz., vartotojai, produktai, užsakymai).
  2. Sukurkite atskirus modulius kiekvienai ribai, apibrėždami su ta riba susijusius tipus, užklausas ir mutacijas.
  3. Naudokite importo/eksporto mechanizmus (priklausomai nuo jūsų GraphQL serverio įgyvendinimo), kad sujungtumėte modulius į vieną, unifikuotą schemą.

Pavyzdys (naudojant JavaScript/Node.js):

Sukurkite atskirus failus kiekvienam moduliui:

  
    // vartotojai.graphql
    type User {
      id: ID!
      name: String!
      email: String!
    }

    type Query {
      user(id: ID!): User
    }

    // produktai.graphql
    type Product {
      id: ID!
      name: String!
      price: Float!
    }

    type Query {
      product(id: ID!): Product
    }
  

Tada sujunkite juos pagrindiniame schemos faile:

  
    // schema.js
    const { makeExecutableSchema } = require('graphql-tools');
    const { typeDefs: userTypeDefs, resolvers: userResolvers } = require('./users');
    const { typeDefs: productTypeDefs, resolvers: productResolvers } = require('./products');

    const typeDefs = [
      userTypeDefs,
      productTypeDefs,
      ""
    ];

    const resolvers = {
      Query: {
        ...userResolvers.Query,
        ...productResolvers.Query,
      }
    };

    const schema = makeExecutableSchema({
      typeDefs,
      resolvers,
    });

    module.exports = schema;
  

Privalumai:

Svarstytini aspektai:

4. Sąsajų ir junginių tipai

Sąsajų (Interface) ir junginių (Union) tipai leidžia apibrėžti abstrakčius tipus, kuriuos gali įgyvendinti keli konkretūs tipai. Tai naudinga reprezentuojant polimorfinius duomenis – duomenis, kurie gali įgyti skirtingas formas priklausomai nuo konteksto.

Kaip tai veikia:

Pavyzdys:

  
    interface Node {
      id: ID!
    }

    type User implements Node {
      id: ID!
      name: String!
      email: String!
    }

    type Product implements Node {
      id: ID!
      name: String!
      price: Float!
    }

    union SearchResult = User | Product

    type Query {
      node(id: ID!): Node
      search(query: String!): [SearchResult!]!
    }
  

Šiame pavyzdyje tiek User, tiek Product įgyvendina Node sąsają, kuri apibrėžia bendrą id lauką. SearchResult junginio tipas reprezentuoja paieškos rezultatą, kuris gali būti arba User, arba Product. Klientai gali siųsti užklausą į `search` lauką ir tada naudoti `__typename` lauką, kad nustatytų, kokio tipo rezultatą jie gavo.

Privalumai:

Svarstytini aspektai:

5. Ryšio modelis (Connection Pattern)

Ryšio modelis yra standartinis būdas įgyvendinti puslapiavimą GraphQL API. Jis suteikia nuoseklų ir efektyvų būdą gauti didelius duomenų sąrašus dalimis.

Kaip tai veikia:

Pavyzdys:

  
    type User {
      id: ID!
      name: String!
      email: String!
    }

    type UserEdge {
      node: User!
      cursor: String!
    }

    type UserConnection {
      edges: [UserEdge!]!
      pageInfo: PageInfo!
    }

    type PageInfo {
      hasNextPage: Boolean!
      hasPreviousPage: Boolean!
      startCursor: String
      endCursor: String
    }

    type Query {
      users(first: Int, after: String, last: Int, before: String): UserConnection!
    }
  

Privalumai:

Svarstytini aspektai:

Globalūs aspektai

Projektuojant GraphQL schemą globaliai auditorijai, atsižvelkite į šiuos papildomus veiksnius:

Pavyzdžiui, apsvarstykite produkto aprašymo lauką:


type Product {
 id: ID!
 name: String!
 description(language: String = "en"): String!
}

Tai leidžia klientams prašyti aprašymo konkrečia kalba. Jei kalba nenurodyta, numatytoji yra anglų (`en`).

Išvados

Mąstelio keitimui pritaikytas schemos projektavimas yra būtinas norint sukurti tvirtas ir lengvai prižiūrimas GraphQL API, galinčias atlaikyti globalios programos reikalavimus. Laikydamiesi šiame straipsnyje aprašytų principų ir naudodami tinkamus projektavimo modelius, galite sukurti API, kurias lengva suprasti, keisti ir plėsti, kartu užtikrinant puikų našumą ir mastelio keitimą. Nepamirškite modularizuoti, komponuoti ir abstrahuoti savo schemą bei atsižvelgti į specifinius jūsų globalios auditorijos poreikius.

Taikydami šiuos modelius, galite atskleisti visą GraphQL potencialą ir sukurti API, kurios maitins jūsų programas ateinančius metus.